﻿#include "Menu.h"
#include <Windows.h>
#include "Config.h"
#include "Renderer.h"
#include <windows.h>
#include <winnls.h>
#include <iostream>
#include "GlobalVars.h"
#include "baidu_font.h"

extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	if (Menu::get().showMenu && ImGui_ImplWin32_WndProcHandler(hwnd, msg, wParam, lParam))
	{
		return true;
	}
	return CallWindowProc(Menu::get().wndproc_orig, hwnd, msg, wParam, lParam);
}

void Menu::init()
{
	if (!isInit)
	{
		//wndproc_orig = (WNDPROC)SetWindowLongPtr(GlobalVars::get().overlayHWindow, GWLP_WNDPROC, (LONG_PTR)WndProc);
		// imgui结构检查
		IMGUI_CHECKVERSION();
		// 初始化imgui
		ImGui::CreateContext();
		// 获取imgui
		ImGuiIO & io = ImGui::GetIO();
		// 设置不生成imgui窗口位置存贮
		io.WantSaveIniSettings = false;
		io.IniFilename = NULL;
		// 设置imgui窗口样式
		//ImGui::StyleColorsDark();
		ImGui::StyleColorsClassic();
		// 初始化cpu频率和当前开机时间以及事件类型
		ImGui_ImplWin32_Init(GlobalVars::get().overlayHWindow);
		// 保存dx11到imgui设备和上下文
		ImGui_ImplDX11_Init(Renderer::get().pD3DDevice, Renderer::get().pD3DDeviceContext);

		// 加载内存字体，并转移所有权
		ImFontConfig f_cfg1;
		f_cfg1.FontDataOwnedByAtlas = false;
		// 好像是最先加载的字体作为菜单窗口的字体
		pMenuFont = io.Fonts->AddFontFromMemoryTTF((void *)baidu_font_data, baidu_font_size, 25.0f, &f_cfg1, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());

		ImFontConfig f_cfg2;
		f_cfg2.FontDataOwnedByAtlas = false;
		pEspFont = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\msyh.ttc", 17.0f, &f_cfg2, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());

		// 窗口位置
		//ImGui::SetWindowPos(u8"骚操作辅助", { 230.f, 250.f });

		isInit = true;
	}
}

void Menu::drawMainMenu()
{
	// 状态切换
	switchState();

	init();
	// 创建dx11着色器以及字体
	ImGui_ImplDX11_NewFrame();
	// 获取当前系统鼠标 键盘 游戏手柄的信息
	ImGui_ImplWin32_NewFrame();
	// 全局数据更新
	ImGui::NewFrame();

	// 菜单隐藏，不绘制菜单
	if (!showMenu)
	{
		return;
	}
	{
		ImGui::Begin(u8"我爱中国");
		ImGui::TextColored(ImColor(220, 20, 60, 255), u8"【Ins】隐藏/显示菜单");

		ImGui::TextColored(ImColor(0, 191, 255, 255), u8"透视选项");
		if (ImGui::BeginTable("split", 2))
		{
			ImGui::TableNextColumn(); ImGui::Checkbox(u8"方框透视  【F1】", &Config::get().boxEsp);
			ImGui::TableNextColumn(); ImGui::Checkbox(u8"连线透视  【F2】", &Config::get().lineEsp);
			ImGui::TableNextColumn(); ImGui::Checkbox(u8"骨头透视  【F3】", &Config::get().skeletonEsp);
			ImGui::TableNextColumn(); ImGui::Checkbox(u8"血条透视  【F4】", &Config::get().hpEsp);
			ImGui::TableNextColumn(); ImGui::Checkbox(u8"距离透视  【F5】", &Config::get().distanceEsp);
			ImGui::EndTable();
		}

		ImGui::TextColored(ImColor(0, 191, 255, 255), u8"透视颜色");
		static int espColorIndex = 0;
		ImGui::RadioButton(u8"红", &espColorIndex, 0); ImGui::SameLine();
		ImGui::RadioButton(u8"黄", &espColorIndex, 1); ImGui::SameLine();
		ImGui::RadioButton(u8"蓝", &espColorIndex, 2); ImGui::SameLine();
		ImGui::RadioButton(u8"绿", &espColorIndex, 3);
		switch (espColorIndex)
		{
			case 0:
				Config::get().espColor = Color::Red;
				break;
			case 1:
				Config::get().espColor = Color::Yellow;
				break;
			case 2:
				Config::get().espColor = Color::Blue;
				break;
			case 3:
				Config::get().espColor = Color::Green;
				break;
			default:
				break;
		}

		ImGui::SliderInt(u8"透视范围", &Config::get().espRange, 0, 500);

		ImGui::TextColored(ImColor(0, 191, 255, 255), u8"射击选项");
		ImGui::Checkbox(u8"自苗锁定  【F6】", &Config::get().aimbot);
		ImGui::SameLine();
		ImGui::RadioButton(u8"头部", &Config::get().aimbotType, 0); ImGui::SameLine();
		ImGui::RadioButton(u8"胸部", &Config::get().aimbotType, 1);
		ImGui::SliderInt(u8"自苗范围", &Config::get().aimbotRange, 0, 500);
		ImGui::Checkbox(u8"无后坐力", &Config::get().noRecoil);
		ImGui::Checkbox(u8"无限子弹", &Config::get().lockBullet);

		ImGui::TextColored(ImColor(0, 191, 255, 255), u8"其他功能");
		ImGui::Checkbox(u8"无限血量", &Config::get().lockHp);

		ImGui::Text(u8"人物速度");
		ImGui::SameLine();
		if (ImGui::Button(u8"原速"))
		{
			Config::get().moveSpeed = 1.0f;
			Renderer::get().increaseSpeed();
		}
		ImGui::SameLine();
		if (ImGui::Button(u8"2倍速度"))
		{
			Config::get().moveSpeed = 2.0f;
			Renderer::get().increaseSpeed();
		}
		ImGui::SameLine();
		if (ImGui::Button(u8"5倍速度"))
		{
			Config::get().moveSpeed = 5.0f;
			Renderer::get().increaseSpeed();
		}
		ImGui::SameLine();
		if (ImGui::Button(u8"10倍速度"))
		{
			Config::get().moveSpeed = 10.0f;
			Renderer::get().increaseSpeed();
		}


		ImGui::TextColored(ImColor(220, 20, 60, 255), u8"请隐藏菜单再进行游戏！！！");
		ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
		ImGui::End();
	}
}

// 热键控制 & 0x8000：自瞄 & 1：菜单切换
void Menu::switchState()
{
	// 控制窗口显示/隐藏
	if (GetAsyncKeyState(VK_INSERT) & 1)
	{
		showMenu = !showMenu;
		if (showMenu)
		{
			// 显示菜单，让鼠标不穿透透明窗口
			SetWindowLongPtr(GlobalVars::get().overlayHWindow, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW);
		}
		else
		{
			// 隐藏菜单，让鼠标穿透透明窗口
			SetWindowLongPtr(GlobalVars::get().overlayHWindow, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_TOOLWINDOW);
		}
	}

	if (GetAsyncKeyState(VK_F1) & 1)
	{
		Config::get().boxEsp = !Config::get().boxEsp;
	}

	if (GetAsyncKeyState(VK_F2) & 1)
	{
		Config::get().lineEsp = !Config::get().lineEsp;
	}

	if (GetAsyncKeyState(VK_F3) & 1)
	{
		Config::get().skeletonEsp = !Config::get().skeletonEsp;
	}

	if (GetAsyncKeyState(VK_F4) & 1)
	{
		Config::get().hpEsp = !Config::get().hpEsp;
	}

	if (GetAsyncKeyState(VK_F5) & 1)
	{
		Config::get().distanceEsp = !Config::get().distanceEsp;
	}

	if (GetAsyncKeyState(VK_F6) & 1)
	{
		Config::get().aimbot = !Config::get().aimbot;
	}
}

void Menu::endMenuScene()
{
	// 提交imgui绘制数据
	ImGui::Render();
	// 绑定到渲染管线
	Renderer::get().pD3DDeviceContext->OMSetRenderTargets(1, &Renderer::get().pMainRenderTargetView, NULL);
	// 清空屏幕
	Renderer::get().pD3DDeviceContext->ClearRenderTargetView(Renderer::get().pMainRenderTargetView, (float *)&clearColor);

	// 将imgui的绘制数据绘制到dx11
	ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
	// 呈现，开启垂直同步
	Renderer::get().pSwapChain->Present(1, 0);
}
